<template>
  <ul class="pagination">
    <li class="prev" @click="prevNext(-1)">上一页</li>
    <li
      v-for="(p, index) in pages"
      :key="p + index"
      :class="{ current: p === current }"
      @click="changeCurrent(p)"
    >
      {{ p }}
    </li>
    <li class="next" @click="prevNext(1)">下一页</li>
  </ul>
</template>

<script>
export default {
  name: 'Pagination',
  props: {
    // 总共多少条
    total: {
      required: true,
      type: Number,
      validator(value) {
        return value >= 0
      },
    },
    // 每页多少条
    pageSize: {
      required: true,
      type: Number,
    },
    // 当前第几页
    current: {
      required: true,
      type: Number,
      validator(value) {
        return value >= 1
      },
    },
  },

  computed: {
    totalPages() {
      return Math.ceil(this.total / this.pageSize)
    },
    pages() {
      const { current } = this
      const p = [
        1,
        current - 2,
        current - 1,
        current,
        current + 1,
        current + 2,
        this.totalPages,
      ]

      return this.unique(p)
        .filter((item) => item >= 1 && item <= this.totalPages)
        .sort((a, b) => a - b)
        .reduce((accu, current, index, array) => {
          const next = array[index + 1]
          accu.push(current)
          if (next && next - current > 1) {
            accu.push('...')
          }
          return accu
        }, [])
    },
  },

  methods: {
    unique(arr) {
      const m = {}
      arr.forEach((n) => {
        m[n] = true
      })
      return Object.keys(m).map((num) => parseInt(num, 10))
    },

    changeCurrent(c) {
      if (c !== '...') {
        this.$emit('update:current', c)
        this.$emit('change-current', c)
      }
    },

    prevNext(d) {
      const t = this.current + d
      if (t >= 1 && t <= this.totalPages) {
        this.changeCurrent(t)
      }
    }
  },
}
</script>

<style scoped>
ul,
li {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  list-style-type: none;
}
.pagination {
  display: flex;
}
.pagination > li {
  display: inline-block;
  vertical-align: middle;
  text-align: center;
  min-width: 30px;
  padding: 0 4px;
  height: 28px;
  line-height: 28px;
  margin: 0 5px;
  font-size: 13px;
  color: #606266;
  background-color: #f4f4f5;
  border-radius: 2px;
  cursor: pointer;
}

.pagination > li.current {
  background-color: #409eff;
  color: #fff;
}
.pagination .prev, .pagination .next {
  padding: 0 10px;
}
</style>